package main

import (
	"fmt"
	"sync"
)

func doWork(id int,
	in chan int, wg *sync.WaitGroup) {
	// range 读取 in channel 数据
	for n := range in {
		// 处理 in 接收的数据
		fmt.Printf("Worker %d received %c\n",
			id, n)
		// 反馈信息， 已经处理完了
		wg.Done()
	}
}

type worker struct {
	 in chan int
	 // 添加 WaitGroup
	 wg *sync.WaitGroup  // 使用指针， 调用同一份。 不能是单独的
}


// 创建工作
func createWorker(id int, wg *sync.WaitGroup) worker {
	w := worker {
		in: make(chan int),
		wg: wg,
	}
	go doWork(id, w.in, w.wg)
	return w
}

// 例子
func chanDemo() {
	// 创建 WaitGroup
	var wg sync.WaitGroup
	// 创建十个 工人
	var workers [10]worker
	for i := 0; i < 10; i++ {
		workers[i] = createWorker(i, &wg)
	}

	// 我们下面设置的 一共20个任务
	wg.Add(20)

	// 给每个工人分配任务, 传入一个值
	for i, worker := range workers {
		worker.in <- 'A' + i
		// 除了一次性Add(20), 当不知道总的 任务数时， 可以再这里，每创建一个 Add(1)
	}

	// 给每个工人分配任务, 再传入一个值
	for i, worker := range workers {
		worker.in <- 'a' + i
	}

	// 等待
	wg.Wait()


	//var wg sync.WaitGroup
	//wg.Add()  // 接收int 类型： 任务数   用在接收者
	//wg.Done()  // 任务处理结束标志   用在处理者
	//wg.Wait()  // 等待所有任务结束   用在处理者
}

func main() {
	chanDemo()
}
